<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 引入vue2.0版本 -->
    <script src="../js/vue.js"></script>
    <title>回顾Object.defineProperty</title>
  </head>
  <!-- 

    对象的属性有2种:
            1.数据属性 （既可以直接定义，也可以通过defineProperty来定义，直接定义数据属性4个特性都为true,通过defineProperty来定义4个特性如果不设置默认为false）
            2.访问器属性 （访问器属性不能直接定义，必须通过defineProperty来定义，通过defineProperty来定义4个特性如果不设置默认为false）
                （1）访问器属性不包含数据值；它们包含一对儿get 和set 函数（不过，这两个函数都不是必需的）。
                （2）在读取访问器属性时，会调用get 函数，这个函数负责返回有效的值；
                （3）在写入访问器属性时，会调用set 函数并传入新值，这个函数负责决定如何处理数据
                
            3.注意:每个对象都有n个属性,每个数据属性都有4个描述其行为的特性
                        1.configurable:是否可delete        已有属性默认:true
                        2.enumerable:是否可枚举遍历         已有属性默认:true
                        3.writable:是否可修改               已有属性默认:true
                        4.value:属性的数据值                已有属性默认:undefined


            4.Object.defineProperty()
                        通过Object.defineProperty()方法也可以来定义对象的属性
                        如果不指定， configurable， enumerable， writable特性的默认值都是false

            5.问题来了？我直接定义属性简单方便为什么还有Object.defineProperty()?
                (1)一个东西不会平白无故的出现Object.defineProperty()可以设置数据属性的4个特性，如果直接定义4个数据属性只能是true
                (2)Object.defineProperty()可以定义访问器属性，因为访问器属性不可以直接定义自定义的get和set函数，是能是默认的

              注意：Object.defineProperty()不能同时指定访问器属性和值或可写属性




            
 -->

  <body>
    <div id="root"></div>
    <script type="text/javascript">
      Vue.config.productionTip = false //以阻止vue在启动时生成生产提示
      let person = {
        name: '名师',
      }

      // 需求1：添加属性age为18
      let number = 19

      Object.defineProperty(person, 'age', {
        // 注意：Object.defineProperty()不能同时指定访问器属性和值或可写属性

        // 数据属性的4个特性
        // value: 18,
        // writable: true,//默认为false
        configurable: true, //默认为false,是否可删除
        enumerable: true, // 如果不设置enumerable为true，默认为false，这样设置的内容显示为浅色，想表达的是不可以被枚举的

        // 我们说的数据属性默认为false是使用Object.defineProperty这个方法，平时我们直接定义得属性都默认为true

        // 访问器属性：
        // 当有人读取person的属性时，get函数(getter)就会被调用，且返回值就是age的值

        //1.为什么get函数要简称getter？
        // 我们可以看下定义之后属性值是三个点...,鼠标放上去为"Invoke property getter"
        // Invoke property getter:翻译过来就是调用属性getter
        // get是属性名称，属性值是一个函数，这个属性被官方叫做getter

        // get: function hhh() {
        //     return number //每次读取都会调用getter
        // },

        // // 当有人修改person的age属性时，set函数（setter）就会被调用，且收到修改的具体值
        // set: function zzz(value) {
        //     number = value  //每次修改都会调用setter
        // }

        // 一般简写为
        get() {
          return number
        },
        set(value) {
          number = value
        },
      })
      console.log(person)
    </script>
  </body>
</html>
